<?php

declare(strict_types=1);

namespace App\Services;

use App\Entity\ProductCategoryEntity;
use App\Entity\ProductEntity;
use App\Inc\OrderInc;
use App\Models\HomepageRecommend;
use App\Models\Product;
use App\Models\ProductRange;
use App\Models\ProductsCategory;
use App\Services\api\IProductService;
use App\Services\api\IProductSkuService;
use App\Utils\ImageUtil;

class ProductService implements IProductService
{
    /**
     * @param array
     * @param int
     * @return array
     */
    public function getProductsByBtype(array $btype, int $cityId)
    {
        $products = Product::query()->whereIn('btype', $btype)->whereIn('id', ProductRange::getCityProductIds($cityId))->get();
        if (!$products) {
            return [];
        }

        foreach ($products as $key => $product) {
            //详情不输出
            $products[$key]->description = '';

            $productEntity = new ProductEntity($product);

            $skus = $this->getProductSkuService()->getProductSkus($productEntity);

            $cityIsOpen = $this->cityIsOpen($productEntity->getId(), $cityId);

            if ($productEntity->getOnSale() == OrderInc::PRODUCT_ON_SALE_开启 && $cityIsOpen) {
                $products[$key]['is_show'] = 1;
            } else {
                $products[$key]['is_show'] = 0;
            }

            $products[$key]['hot_on_image']               = ImageUtil::groupImageUrl($productEntity->getProductMenuImage());
            $products[$key]['banner1_image']              = ImageUtil::groupImageUrl(OrderInc::BTYPE_CONFIG[$product->btype]['banner1_image']);
            $products[$key]['product_desc']               = OrderInc::BTYPE_CONFIG[$product->btype]['product_desc'];
            $products[$key]['recommend_left1_image']      = ImageUtil::groupImageUrl(OrderInc::BTYPE_CONFIG[$product->btype]['recommend_left1_image']);
            $products[$key]['recommend_left2_image']      = ImageUtil::groupImageUrl(OrderInc::BTYPE_CONFIG[$product->btype]['recommend_left2_image']);
            $products[$key]['recommend_right1_image']     = ImageUtil::groupImageUrl(OrderInc::BTYPE_CONFIG[$product->btype]['recommend_right1_image']);
            $products[$key]['recommend_right2_image']     = ImageUtil::groupImageUrl(OrderInc::BTYPE_CONFIG[$product->btype]['recommend_right2_image']);
            $products[$key]['product_unit']               = OrderInc::BTYPE_CONFIG[$product->btype]['product_unit'];
            $products[$key]['recommend_double11_image']   = ImageUtil::groupImageUrl(OrderInc::BTYPE_CONFIG[$product->btype]['recommend_double11_image']);
            $products[$key]['satisfaction_rate']          = OrderInc::BTYPE_CONFIG[$product->btype]['satisfaction_rate'];
            $products[$key]['chuman_shajun_taocan_image'] = ImageUtil::groupImageUrl(OrderInc::BTYPE_CONFIG[$product->btype]['chuman_shajun_taocan_image']);
            $products[$key]['reginal_image']              = ImageUtil::groupImageUrl(OrderInc::BTYPE_CONFIG[$product->btype]['reginal_image']);
            $products[$key]['reginal_desc']               = OrderInc::BTYPE_CONFIG[$product->btype]['reginal_desc'];

            $products[$key]['old_price'] = '';
            if ($skus->isNotEmpty()) {
                $products[$key]['old_price'] = $skus->first()['price'];
                if ($skus->first()['product_id'] == 1 && $skus->first()['city_id'] == 540) {
                    // 上海 sku 特殊处理下
                    $products[$key]['old_price'] = 45;
                }
            }
        }

        return $products->toArray();
    }

    /**
     * @return array
     */
    public function getIndexProducts(string $typeName, int $cityId)
    {
        switch ($typeName) {
            case 'hot':
                $btypeArr = OrderInc::BTYPE_HOT;
                break;
            case 'jiadianchuman':
                $btypeArr = OrderInc::BTYPE_APPLIANCES_PACKAGE;
                break;
            case 'reginal':
                $btypeArr = OrderInc::BTYPE_REGIONAL;
                break;
            case 'recommend':
                $btypeArr = OrderInc::BTYPE_RECOMMEND;
                break;
            default:
                return [];
        }
        $productArray = $this->getProductsByBtype($btypeArr, $cityId);
        $is_show = array_column($productArray, 'is_show');
        $sort = array_column($productArray, 'sort');
        switch ($typeName) {
            case 'hot':
            case 'jiadianchuman':
            case 'reginal':
                array_multisort($is_show, SORT_DESC, $productArray);
                break;
            case 'recommend':
                array_multisort($sort, SORT_DESC, $productArray);
                break;
        }

        return $productArray;
    }

    /**
     * @return ProductEntity/null
     */
    public function findOne(int $productId)
    {
        return ProductEntity::find($productId);
    }

    /**
     * @return array
     */
    public function getHomepageRecommend(int $cityId)
    {
        $cityRecommendObjs = HomepageRecommend::getCityRecommend($cityId);
        $data              = [];
        if ($cityRecommendObjs) {
            $cityUniques = []; //城市独有配置
            foreach ($cityRecommendObjs as $recommendObj) {
                if ($recommendObj->city_id > 0) {
                    $cityUniques[] = $recommendObj->product_id;
                }
            }
            foreach ($cityRecommendObjs as $index => $recommendObj) {
                if (!$recommendObj->city_id && in_array($recommendObj->product_id, $cityUniques)) {
                    unset($cityRecommendObjs[$index]);
                    continue;
                }
                $data[] = $recommendObj->toArray();
            }
        }

        return $data;
    }

    /**
     * {@inheritdoc}
     */
    public function cityIsOpen(int $productId, int $cityId)
    {
        $model = ProductRange::where([
            'product_id' => $productId,
            'area_level' => 1,
            'area_code'  => $cityId,
        ])->first();

        return $model ? true : false;
    }

    public function getCityProductList(int $cityId)
    {
        $productList = [];
        $productIds  = ProductRange::getCityProductIds($cityId);
        foreach ((array) $productIds as $productId) {
            $productList[] = $this->findOne($productId)->toArray();
        }

        return $productList;
    }

    /**
     * @return IProductSkuService
     */
    private function getProductSkuService()
    {
        return app(IProductSkuService::class);
    }

    /**
     * @param int $productId
     * @return \App\Entities\ProductEntity|ProductEntity|null
     */
    public function getProductEntityById(int $productId)
    {
        return ProductEntity::find($productId);
    }

    /**
     * @param int $categoryId
     * @param bool $onSale
     * @return ProductEntity[]
     */
    public function getProductsByCategoryId(int $categoryId, bool $onSale = true): array
    {
        $sale = 1;
        if (!$onSale) {
            $sale = 2;
        }
        $products = ProductEntity::where('product_category_id', $categoryId)->where('on_sale', $sale)->get()->all();
        if (empty($products)) {
            return [];
        }
        $arr = [];
        foreach ($products as $product) {
            $arr[] = new ProductEntity($product);
        }
        return $arr;
    }

    /**
     * @param bool $onSale
     * @return ProductEntity[]
     */
    public function getAllProducts(bool $onSale = true): array
    {
        $sale = 1;
        if (!$onSale) {
            $sale = 2;
        }

        $category = ProductsCategory::all();
        if (empty($category)) {
            return [];
        }
        $categoryIds = [];
        foreach ($category as $item) {
            $productCategoryEntity = new ProductCategoryEntity($item);
            $categoryIds[] = $productCategoryEntity->getId();
        }

        $products = Product::whereIn('product_category_id', $categoryIds)->where('on_sale', $sale)->get()->all();
        if (empty($products)) {
            return [];
        }
        $arr = [];
        foreach ($products as $product) {
            $arr[] = new ProductEntity($product);
        }
        return $arr;
    }
}
